package pers.lonestar.framework.utils.support.utils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import pers.lonestar.framework.utils.support.annotations.ExcelColumnIgnore;
import pers.lonestar.framework.utils.support.annotations.ExcelColumnProperty;
import pers.lonestar.framework.utils.support.annotations.ExcelIgnoreUnannotated;
import pers.lonestar.framework.utils.support.comparators.FieldIndexComparator;
import pers.lonestar.framework.utils.support.converters.Converter;
import pers.lonestar.framework.utils.support.exception.ExcelConvertException;

public class FieldUtil {
    public static List<Field> getSortedDeclaredFieldList(Class<?> clazz) {
        List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
        if (clazz.getAnnotation(ExcelIgnoreUnannotated.class) != null) {
            fields = fields.stream().filter(field -> field.getAnnotation(ExcelColumnProperty.class) != null && field.getAnnotation(ExcelColumnIgnore.class) == null).collect(Collectors.toList());
        } else {
            fields = fields.stream().filter(field -> field.getAnnotation(ExcelColumnIgnore.class) == null).collect(Collectors.toList());
        }
        fields.sort(new FieldIndexComparator());
        return fields;
    }

    public static List<String> getSortedDeclaredFieldNameList(List<Field> fieldList) {
        return fieldList.stream().map(Field::getName).collect(Collectors.toList());
    }

    public static List<String> getSortedDeclaredFieldNameList(Class<?> clazz) {
        return getSortedDeclaredFieldList(clazz).stream().map(Field::getName).collect(Collectors.toList());
    }

    public static List<Converter> getSortedDeclaredFieldConverterList(List<Field> fieldList) {
        return fieldList.stream().map(field -> {
            ExcelColumnProperty columnProperty = field.getAnnotation(ExcelColumnProperty.class);
            try {
                return columnProperty == null ? null : columnProperty.converter().newInstance();
            } catch (Exception e) {
                throw new ExcelConvertException("Can not instance custom converter class: " + columnProperty.converter().getName());
            }
        }).collect(Collectors.toList());
    }

    public static List<Converter> getSortedDeclaredFieldConverterList(Class<?> clazz) {
        return getSortedDeclaredFieldList(clazz).stream().map(field -> {
            ExcelColumnProperty columnProperty = field.getAnnotation(ExcelColumnProperty.class);
            try {
                return columnProperty == null ? null : columnProperty.converter().newInstance();
            } catch (Exception e) {
                throw new ExcelConvertException("Can not instance custom converter class: " + columnProperty.converter().getName());
            }
        }).collect(Collectors.toList());
    }
}
